/*!
 * aForm JavaScript Library v1.2
 * https://aform.stu.red/
 *
 * Copyright yihrmc
 * Email: a@stu.red
 * version: 1.2
 * Date: 2018-10-15
 */
(function(factory) {

	if(!window.console) {
		window.console = {
			log: function(text) {},
			info: function(text) {},
			debug: function(text) {},
			error: function(text) {},
			clear: function(text) {}
		};
	}

	/*function createStyleSheet() {
		var head = document.head || document.getElementsByTagName('head')[0];
		var style = document.createElement('style');
		if(!style) {
			return {
				addCssRule: function(selector, rules, index) {
					console.info("浏览器不支持createStyleSheet()")
				}
			};
		}
		style.type = 'text/css';
		head.appendChild(style);
		var styleSheet = style.sheet || style.styleSheet;
		styleSheet.addCssRule = function(selector, rules, index) {
			var _this = this;
			index = index || 0;
			if(_this.insertRule) {
				_this.insertRule(selector + "{" + rules + "}", index);
			} else if(styleSheet.addRule) {
				_this.addRule(selector, rules, index);
			}
		}
		return styleSheet;
	}*/

	/* 放弃JS创建css样式，请编写自写CSS  */
	/*
	createStyleSheet().addCssRule("[aui-view] *", "visibility: hidden;");
	*/

	if(!Function.prototype.bind) {
		Function.prototype.bind = function(oThis) {
			if(typeof this !== 'function') {
				// closest thing possible to the ECMAScript 5
				// internal IsCallable function
				throw new TypeError('Function.prototype.bind - what is trying to be bound is not callable');
			}
			var aArgs = Array.prototype.slice.call(arguments, 1),
				fToBind = this,
				fNOP = function() {},
				fBound = function() {
					return fToBind.apply(this instanceof fNOP ?
						this :
						oThis,
						// 获取调用时(fBound)的传参.bind 返回的函数入参往往是这么传递的
						aArgs.concat(Array.prototype.slice.call(arguments)));
				};

			// 维护原型关系
			if(this.prototype) {
				// Function.prototype doesn't have a prototype property
				fNOP.prototype = this.prototype;
			}
			fBound.prototype = new fNOP();

			return fBound;
		};
	}

	if(!Object.prototype.assign) {
		Object.prototype.assign = function(target) {
			if(typeof target != "object" || arguments.length < 2)
				return target;
			for(var i = 1; i < arguments.length; i++) {
				var loadObj = arguments[i];
				if(typeof loadObj != "object")
					continue;
				for(o in loadObj) {
					if(loadObj.hasOwnProperty(o)) {
						target[o] = loadObj[o];
					}
				}
			}
			return target;
		}
	}
	if(!document.querySelectorAll) {
		//  jQuery() replaces document.querySelectorAll()
		document.querySelectorAll = jQuery;
	}
	if(!Element.prototype.querySelectorAll) {
		Element.prototype.querySelectorAll = function(selectors) {
			return jQuery(this).find(selectors);
		}
	}
	if(!document.querySelector) {
		document.querySelector = function(selectors) {
			var elements = document.querySelectorAll(selectors);
			return(elements.length) ? elements[0] : null;
		};
	}
	if(!Element.prototype.querySelector) {
		Element.prototype.querySelector = function(selectors) {
			var elements = this.querySelectorAll(selectors);
			return(elements.length) ? elements[0] : null;
		}
	}
	if(!Element.prototype.addEventListener) {
		if(Element.prototype.attachEvent) {
			document.addAuiEventListener = Element.prototype.addEventListener = function(type, fn) {
				this.attachEvent('on' + type, fn);
			}
		} else {
			document.addAuiEventListener = Element.prototype.addEventListener = function(type, fn) {
				this['on' + type] = fn;
			}
		}
	}
	if(!Element.prototype.addAuiEventListener) {
		document.addAuiEventListener = Element.prototype.addAuiEventListener = function(type, fn) {
			var eventName, eventDdditional;
			if(!type) {
				return;
			} else {
				var types = type.split(":");
				eventName = types[0].toLowerCase();
				if(types.length > 1) {
					eventDdditional = types[1];
				}
			}
			fn.bind(this);
			switch(eventName) {
				case 'now':
					fn();
					break;
				case 'setInterval':
					if(eventDdditional) {
						setInterval(fn, parseInt(eventDdditional));
					}
					break;
				case 'setTimeout':
					if(eventDdditional) {
						setTimeout(fn, parseInt(eventDdditional));
					}
					break;
				default:
					this.addEventListener(type, fn);
					break;
			}
		}
	}
	if(!Element.prototype.getChildren) {
		document.getChildren = Element.prototype.getChildren = function() {
			var children = this.children || this.childNodes;
			var childrenElems = [];
			for(var i = 0; i < children.length; i++) {
				if(children[i].nodeType == 1) {
					childrenElems.push(children[i]);
				}
			}
			return childrenElems;
		}
	}
	if(!Element.prototype.getNextElementSibling) {
		Element.prototype.getNextElementSibling = function() {
			var _this = this;
			if(_this.nextElementSibling != undefined)
				return _this.nextElementSibling;
			var sibling = _this;
			while ((sibling = sibling.nextSibling) != null) {
				if(sibling.nodeType == 1) {
					return sibling;
				}
			}
			return null;
		}
	}
	if(!Element.prototype.getPreviousElementSibling) {
		Element.prototype.getPreviousElementSibling = function() {
			var _this = this;
			if(_this.previousElementSibling != undefined)
				return _this.previousElementSibling;
			var sibling = _this;
			while ((sibling = sibling.previousSibling) != null) {
				if(sibling.nodeType == 1) {
					return sibling;
				}
			}
			return null;
		}
	}

	if(!Element.prototype.insertAfter) {
		document.insertAfter = Element.prototype.insertAfter = function(newElement) {
			var parent = this.parentNode;
			if(!parent)
				return;
			if(parent.lastChild == this) {
				parent.appendChild(newElement);
			} else {
				parent.insertBefore(newElement, this.nextSibling);
			}
		}
	}

	var defaultTagDisplayMap = {};

	function getDefaultTagDisplay(tagName) {
		tagName = tagName.toLowerCase();
		var display = defaultTagDisplayMap[tagName];
		if(display) {
			return display;
		}
		temp = document.body.appendChild(document.createElement(tagName));
		display = temp.getCurrentStyle("display");
		temp.parentNode.removeChild(temp);
		if(display === "none") {
			display = "block";
		}
		defaultTagDisplayMap[tagName] = display;
		return display;
	}

	if(!Element.prototype.setDisplay) {
		document.setDisplay = Element.prototype.setDisplay = function(show) {
			var _this = this;
			var display = _this.style.display;
			if(show) {
				if(display === "none") {
					display = _this.__aui__display;
				}
				if(!display) {
					display = getDefaultTagDisplay(_this.tagName);
				}
			} else {
				_this.__aui__display = display;
				display = "none";
			}
			_this.style.display = display;
		}
	}

	if(!Element.prototype.findParentAttr) {
		document.setDisplay = Element.prototype.findParentAttr = function(attrName) {
			var _this = this;
			var parent = _this,
				attr;
			while((parent = parent.parentNode) != null) {
				if(!parent.getAuiAttribute)
					continue;
				attr = parent.getAuiAttribute(attrName);
				if(attr)
					return attr;
			}
			return null;
		}
	}

	if(!Element.prototype.getCurrentStyle) {
		Element.prototype.getCurrentStyle = function(prop) {
			var _this = this;
			if(_this.currentStyle) { // IE
				return _this.currentStyle[prop];
			} else if(window.getComputedStyle) { // 非IE
				propprop = prop.replace(/([A-Z])/g, "-$1");
				propprop = prop.toLowerCase();
				return document.defaultView.getComputedStyle(_this, null)[propprop];
			}
			return null;
		}
	}

	/*if(Node) {
		if(!Node.prototype.getOuterHTML) {
			Node.prototype.getOuterHTML = function() {
				if(this.outerHTML)
					return this.outerHTML;
				var cnode = this.cloneNode(true)
				var div = document.createElement("div");
				div.appendChild(cnode);
				var html = div.innerHTML;
				cnode = null;
				return html;
			}
		}
	} else {
		if(!NodeList.prototype.getOuterHTML) {
			NodeList.prototype.getOuterHTML = function() {
				if(this.outerHTML)
					return this.outerHTML;
				var cnode = this.cloneNode(true)
				var div = document.createElement("div");
				div.appendChild(cnode);
				var html = div.innerHTML;
				cnode = null;
				return html;
			}
		}
	}*/

	if(!Element.prototype.getOuterHTML) {
		Element.prototype.getOuterHTML = function() {
			if(this.outerHTML)
				return this.outerHTML;
			var cnode = this.cloneNode(true)
			var div = document.createElement("div");
			div.appendChild(cnode);
			var html = div.innerHTML;
			cnode = null;
			return html;
		}
	}

	if(!Element.prototype.getEndLabel) {
		Element.prototype.getEndLabel = function() {
			var html = this.getOuterHTML();
			var tagName = this.tagName.toLowerCase();
			var endLabel = html.substring(html.length - tagName.length - 3).toLowerCase();
			if(endLabel == '</' + tagName + '>') {
				return endLabel;
			}
			return null;
		}
	}

	// 低版本的浏览器NodeList兼容forEach
	if(window.NodeList && !NodeList.prototype.forEach) {
		NodeList.prototype.forEach = function(callback, thisArg) {
			thisArg = thisArg || window;
			if(!this.length) {
				return;
			}
			for(var i = 0; i < this.length; i++) {
				callback.call(thisArg, this[i], i, this);
			}
		}
	}

	if(!Array.prototype.forEach) {
		Array.prototype.forEach = function forEach(callback, thisArg) {
			var T, k;
			if(this == null) {
				throw new TypeError("this is null or not defined");
			}
			var O = Object(this);
			var len = O.length >>> 0;
			if(typeof callback !== "function") {
				throw new TypeError(callback + " is not a function");
			}
			if(arguments.length > 1) {
				T = thisArg;
			}
			k = 0;
			while(k < len) {
				var kValue;
				if(k in O) {
					kValue = O[k];
					callback.call(T, kValue, k, O);
				}
				k++;
			}
		};
	}

	if(!Array.prototype.indexOf) {
		Array.prototype.indexOf = function(el) {
			for(var i = 0, n = this.length; i < n; i++) {
				if(this[i] === el) {
					return i;
				}
			}
			return -1;
		}
	}

	String.prototype.trim = function() {
		return this.replace(/^\s+|\s+$/g, '');
	}
	Element.prototype.getAttributeSP = function(attr, v) {
		var aui_attr = this.getAuiAttribute(attr);
		if(!aui_attr)
			return null;
		var rs = aui_attr.split(':');
		if(rs.length == 2) {
			return rs[v ? 0 : 1];
		} else {
			return null;
		}
	}
	Element.prototype.getAuiAttribute = function(attr) {
		if(!this.getAttribute)
			return null;
		var aui_attr = this.getAttribute(attr);
		if(!aui_attr)
			return aui_attr;
		if(aui_attr.charAt(0) == '%' && aui_attr.charAt(aui_attr.length - 1) == '%') {
			try{
				return eval(aui_attr.substring(1, aui_attr.length - 1));
			}catch(e){
				console.error(this);
				throw e;
			}
		}
		return aui_attr;
	}

	factory();

})(function() {
	"use strict";

	function urlEncode(param) {
		return Object.keys(param).map(function(key) {
			return encodeURIComponent(key) + "=" + encodeURIComponent(param[key]);
		}).join("&");
	}

	function findDefaultValue() {
		if(arguments.length == 0) {
			return null;
		}
		for(var i = 0; i < arguments.length; i++) {
			if(arguments[i] != null) {
				return arguments[i];
			}
		}
	}

	function loadObjectAttrFun(obj, loadObj) {
		if(typeof obj != "object" || loadObj != "object")
			return obj;
		for(o in loadObj) {
			if(loadObj.hasOwnProperty(o)) {
				obj[o] = loadObj[o];
			}
		}
		return obj;
	}

	var ACookie = {
		getItem: function(c_name) {
			if(document.cookie.length > 0) {
				var c_start = document.cookie.indexOf(c_name + "=");
				if(c_start != -1) {
					c_start = c_start + c_name.length + 1;
					var c_end = document.cookie.indexOf(";", c_start);
					if(c_end == -1) c_end = document.cookie.length;
					return unescape(document.cookie.substring(c_start, c_end));
				}
			}
			return "";
		},
		setItem: function(c_name, value, expiredays) {
			if(!expiredays) {
				expiredays = 3;
			}
			var exdate = new Date();
			exdate.setDate(exdate.getDate() + expiredays);
			document.cookie = c_name + "=" + escape(value) +
				((expiredays == null) ? "" : "; expires=" + exdate.toGMTString());
		},
		removeItem: function(c_name) {
			var expiredays = new Date();
			expiredays.setTime(expiredays.getTime() - 1);
			var value = this.getItem(name);
			document.cookie = c_name + "=" + value + ";expires=" + expiredays.toGMTString();
		}
	}

	var defaultConfig = {
		form: {
			eventMap: {
				"form": "submit",
				"button": "click"
			},
			resultMap: {
				"none": function(url, result, elem, xhr) {
					console.debug("debug - aui-form:none: " + result);
				},
				"remove": function(url, result, elem, xhr) {
					var aui_result = elem.getAttributeSP("aui-result");
					if(!aui_result || !(aui_result = aui_result.trim()) || !elem || !elem.parentElement) {
						console.debug(elem);
						console.debug("aui-form remove error:<" + aui_result + ">");
						return;
					}
					aui_result = aui_result.toUpperCase();
					while((elem = elem.parentElement)) {
						if(elem.tagName.toUpperCase() == aui_result) {
							if(elem.remove) {
								elem.remove();
							} else if(elem.parentElement) {
								elem.parentElement.removeChild(elem);
							} else {
								console.debug(elem);
								console.debug("remove error:<" + aui_result.trim() + ">");
							}
							return;
						}

					}
					console.debug(elem);
					console.debug("remove:<" + aui_result.trim() + ">");
				},
				"function": function(url, result, elem, xhr) {
					var aui_result = elem.getAttributeSP("aui-result");
					if(!aui_result) {
						console.debug(elem);
						console.debug("aui-form function error:" + aui_result);
						return;
					}
					eval(aui_result + "(url, result, elem, xhr)");
				},
				"page": function(url, result, elem, xhr) {
					var aui_result = elem.getAttributeSP("aui-result");
					if(aui_result != null) {
						location.href = aui_result;
					} else {
						console.debug(elem);
						console.debug("aui-form page error location.href:" + aui_result);
					}
				},
				"reload": function(url, result, elem, xhr) {
					location.reload();
				},
				"view": function(url, result, elem, xhr, aform) {
					var aui_result = elem.getAttributeSP("aui-result");
					var aui_viewElems = document.querySelectorAll("[aui-view=" + aui_result + "]");
					window['__' + aui_result] = {
						url: url,
						result: result,
						elem: elem,
						xhr: xhr,
						aform: aform
					};
					for(var i = 0; i < aui_viewElems.length; i++) {
						aform.viewParsing(aui_viewElems[i]);
					}
				}
			}
		}
	};

	/**
	 * AForm
	 * @param {Object} config
	 */
	var AForm = function(config) {
		var _this = this;
		_this._version = "v1.2";
		if(!config)
			config = {};
		if(!config.ui)
			config.ui = {};
		config.get = function(name) {
			if(!name)
				return undefined;
			var value;
			try {
				value = eval("this." + name);
			} catch(e) {
				value = null;
			}
			if(value != null)
				return value;
			for(var i = 1; i < arguments.length; i++) {
				if(arguments[i] != null) {
					return arguments[i];
				}
			}
		};
		if(!config.from)
			config.from = {};
		if(!config.from.resultMap)
			config.from.resultMap = {};
		Object.assign(config.from.resultMap, defaultConfig.form.resultMap);
		_this.config = config;

	}

	AForm.prototype.query = function(auiElem) {
		if(!auiElem)
			return [];
		var queryElems = [];
		var parentElems;
		var aui_scope = auiElem.getAuiAttribute("aui-scope");
		if(!aui_scope) {
			parentElems = [document];
		} else if(aui_scope.toLowerCase() == "this") {
			parentElems = [auiElem];
		} else {
			parentElems = document.querySelectorAll(aui_scope);
		}
		var aui_for = auiElem.getAuiAttribute("aui-for");
		if(!aui_for) {
			aui_for = this.config.get("elem");
			if(!aui_for)
				aui_for = "input";
		}
		for(var x = 0; x < parentElems.length; x++) {
			var elems = parentElems[x].querySelectorAll(aui_for);
			for(var i = 0; i < elems.length; i++) {
				queryElems.push(elems[i]);
			}
		}
		return queryElems;
	}

	/**
	 * 过滤链接器
	 * @param {Object} callThis 指定被调用doFilter方法 this指向
	 * @param {Function} filterFunctions 将链接执行的所有方法
	 */
	function FilterChain(callThis, filterFunctions) {
		if(!callThis)
			callThis = this;
		this.callThis = callThis;
		this.filterFunctions = filterFunctions;
	}

	FilterChain.prototype.doFilter = function() {
		var _this = this;
		var filterFun = _this.filterFunctions.splice(0, 1)[0];
		if(filterFun && typeof filterFun == "function") {
			var params = [];
			if(_this.filterFunctions.length > 0) // The last Function doesn't give filterChain parameters 
				params.push(_this);
			for(var i = 0; i < arguments.length; i++) {
				params.push(arguments[i]);
			}
			filterFun.apply(_this.callThis, params);
		}
	}

	/**
	 * 执行过滤器
	 * @param {Array} filters 被执行过滤器
	 * @param {String} matching 被过滤器匹配的值
	 * @param {Function} callFunction 最终执行方法
	 * @param {Array} params 过滤器参数组
	 */
	AForm.doFilter = function(filters, matching, callFunction, params) {
		if(!filters)
			filters = {};
		if(!matching)
			matching = "";
		var filterFunctions = [];
		for(var filter in filters) {
			if(!filters[filter].urlPatterns || !filters[filter].doFilter)
				continue;
			var urlPatterns = filters[filter].urlPatterns;
			if(typeof urlPatterns == "string")
				urlPatterns = new RegExp(filters[filter].urlPatterns);
			if(matching.search(urlPatterns) == 0) {
				filterFunctions.push(filters[filter].doFilter);
			}
		}
		filterFunctions.push(callFunction);
		var filterChain = new FilterChain(null, filterFunctions);
		filterChain.doFilter.apply(filterChain, params);
	}

	/**
	 * GET Request
	 * @param {String} url
	 * @param {Function} fn
	 * @param {Element} elem
	 * @param {Boolean} async default(true)
	 */
	AForm.prototype.get = function(url, fn, elem, async) {
		var _this = this;
		if(async == undefined) async = true;
		if(elem == undefined) elem = document;
		var xhr;
		if(window.XMLHttpRequest)
			var xhr = new XMLHttpRequest();
		else
			var xhr = new ActiveXObject("Microsoft.XMLHTTP");
		xhr.open('GET', url, async);
		xhr.onreadystatechange = function() {
			if(xhr.readyState == 4) {
				var result = null;
				if(xhr.status == 200 || xhr.status == 304) {
					try {
						result = JSON.parse(xhr.responseText);
					} catch(e) {
						result = xhr.responseText;
					}
				}
				AForm.doFilter(_this.config.get("resultFilter"), url, fn, [url, result, elem, xhr, _this]);
			}
		};
		AForm.doFilter(this.config.get("requestFilter"), url, function(url, data, elem, xhr) {
			xhr.send();
		}, [url, null, elem, xhr]);
	}

	/**
	 * POST Request
	 * @param {String} url
	 * @param {Object} data
	 * @param {Function} fn
	 * @param {Element} elem
	 * @param {Boolean} async default(true)
	 */
	AForm.prototype.post = function(url, data, fn, elem, async) {
		var _this = this;
		if(async == undefined) async = true;
		var xhr;
		if(window.XMLHttpRequest)
			var xhr = new XMLHttpRequest();
		else
			var xhr = new ActiveXObject("Microsoft.XMLHTTP");
		xhr.open('POST', url, async);
		xhr.setRequestHeader("Content-Type",
			"application/x-www-form-urlencoded");
		xhr.onreadystatechange = function() {
			if(xhr.readyState == 4) {
				var result = null;
				if(xhr.status == 200 || xhr.status == 304) {
					try {
						result = JSON.parse(xhr.responseText);
					} catch(e) {
						result = xhr.responseText;
					}
				}
				AForm.doFilter(_this.config.get("resultFilter"), url, fn, [url, result, elem, xhr, _this]);
			}
		};
		AForm.doFilter(this.config.get("requestFilter"), url, function(url, data, elem, xhr) {
			xhr.send(data);
		}, [url, data, elem, xhr]);
		return true;
	}

	AForm.prototype.load = function(scopeElem) {
		var _this = this;
		if(!scopeElem) {
			scopeElem = document;
		}
		if(!AForm.registerUI)
			AForm.registerUI = [];
		for(var i = 0; i < AForm.registerUI.length; i++) {
			var registerFunction = AForm.registerUI[i];
			if(typeof registerFunction == "function")
				registerFunction.call(_this, scopeElem);
		}
	}
	
	/**
	 * 注册aui组件
	 * @param {String} registerName 注册组件名
	 * @param {Function} registerFunction 组件方法
	 * @param {Boolean} notAutoLoad 是否load统一自动加载
	 */
	AForm.register = function(registerName, registerFunction, notAutoLoad) {
		if(typeof registerName != "string")
			return;
		var _this = this;
		if(!_this.registerUI)
			_this.registerUI = [];
		if(!notAutoLoad) {
			_this.registerUI.push(registerFunction);
		}
		registerName = "load" + registerName.substring(0, 1).toUpperCase() + registerName.substring(1);
		AForm.prototype[registerName] = registerFunction;
	}
	
	var aFormElemUtil = {
		getElement: function (elem, functionName) {
			var elemFun = elem[functionName];
			if(typeof elemFun != "function") {
				return undefined;
			}
			while(elem) {
				if (elem.getAttribute("aui-aform") == null) {
					return elem;
				}
				elem = elemFun.call(elem);
			}
			return null;
		}
	};
	
	AForm.register("aForm", function(scopeElem) {
		if(!scopeElem) {
			scopeElem = document;
		}
		var _this = this;
		var aformElements = scopeElem.querySelectorAll("[aui-aform]");
		for (var y1 = 0; y1 < aformElements.length; y1++) {
			var aformElement = aformElements[y1];
			var ar_aui_aform = aformElement.getAuiAttribute("aui-aform");
			var ignoreAttributes = _this.config.get("aform.ignoreAttrs", []);
			ignoreAttributes.push("aui-aform");
			var addedAttrNodes = [],
				elem;
			switch (ar_aui_aform.toLowerCase()){
				case "next":
					elem = aFormElemUtil.getElement(aformElement, "getNextElementSibling");
					if (elem)
						addedAttrNodes.push(elem);
					break;
				
				case "last":
					elem = aFormElemUtil.getElement(aformElement, "getPreviousElementSibling");
					if (elem)
						addedAttrNodes.push(elem);
					break;
				
				case "parent":
					elem = aformElement.parentNode;
					if (elem)
						addedAttrNodes.push(elem);
					break;
				
				case "children":
					addedAttrNodes = aformElement.childNodes;
					break;
					
				default:
					addedAttrNodes = scopeElem.querySelectorAll(ar_aui_aform);
				
			}
			var attributes = aformElement.attributes;
			for (var y2 = 0; y2 < attributes.length; y2++) {
				var attribute = attributes[y2];
				if(ignoreAttributes.indexOf(attribute.name) != -1) {
					continue;
				}
				for (var i = 0; i < addedAttrNodes.length; i++) {
					if( addedAttrNodes[i].nodeType == 1 &&
							addedAttrNodes[i].getAttribute(attribute.name) == null ) {
						addedAttrNodes[i].setAttribute(attribute.name, attribute.value);
					}
				}
			}
			aformElement.parentNode.removeChild(aformElement);
		}
	});

	AForm.register("meta", function(scopeElem) {
		if(!scopeElem) {
			scopeElem = document;
		}
		var metas = scopeElem.getElementsByTagName('meta');
		for(var i = 0; i < metas.length; i++) {
			var meta = metas[i];
			var auto = meta.getAuiAttribute("aui-auto");
			if(!auto) {
				continue;
			} else {
				auto = auto.toLowerCase();
			}
			var name = meta.name,
				value = meta.getAuiAttribute("content");
			if(auto == 'cookie') {
				ACookie.setItem(name, value, 362);
			} else if(auto == 'session' || auto == 'sessionStorage') {
				sessionStorage.setItem(name, value);
			} else if(auto == 'local' || auto == 'localStorage') {
				localStorage.setItem(name, value);
			} else if(auto == 'var' || auto == 'window' || auto == 'js') {
				window[name] = value;
			}
		}
	});

	AForm.register("checkbox", function(scopeElem) {
		if(!scopeElem) {
			scopeElem = document;
		}
		var _this = this;
		var ui_checkbox = _this.config.get("ui.checkbox", ".aui-checkbox");
		var ui_checkboxs = scopeElem.querySelectorAll(ui_checkbox);
		for(var y1 = 0; y1 < ui_checkboxs.length; y1++) {
			var checkboxElem = ui_checkboxs[y1];
			if(!checkboxElem)
				continue;
			// build event
			var aui_event = findDefaultValue(checkboxElem.getAuiAttribute("aui-event"),
				_this.config.get("checkbox.eventMap", defaultConfig.form.eventMap));
			if(typeof aui_event == "object") {
				aui_event = aui_event[checkboxElem.tagName.toLowerCase()];
				if(!aui_event) {
					aui_event = "change";
				}
			} else if(typeof aui_event != "string") {
				continue;
			}
			checkboxElem.addAuiEventListener(aui_event, function() {
				var _thisElem = this;
				if(typeof _thisElem.checked == "undefined") {
					_thisElem.checked = true;
				}
				var checked = _thisElem.checked;
				var childElems = _this.query(checkboxElem);
				for(var i = 0; i < childElems.length; i++) {
					childElems[i].checked = checked;
				}
				_thisElem.checked = !checked;
			});
		}

	});

	AForm.register("from", function(scopeElem) {
		if(!scopeElem) {
			scopeElem = document;
		}
		var _this = this;
		var ui_form = _this.config.get("ui.form", ".aui-form");
		var aui_checkErrorFunction = _this.config.get("from.checkErrorFunction", function(elem, attrName, attrValue, paramName, paramValue) {
			alert("数据校验出错:" + attrName + ": " + attrValue + ">" + paramName + "," + paramValue);
			return false;
		});
		var formElems = scopeElem.querySelectorAll(ui_form);
		for(var y1 = 0; y1 < formElems.length; y1++) {
			var formElem = formElems[y1];
			if(!formElem || !formElem.tagName)
				continue;
			var aui_action = formElem.getAuiAttribute("aui-action");
			if(aui_action == null)
				continue;
			// build event
			var aui_event = findDefaultValue(formElem.getAuiAttribute("aui-event"),
				_this.config.get("form.eventMap", defaultConfig.form.eventMap));
			if(typeof aui_event == "object") {
				aui_event = aui_event[formElem.tagName.toLowerCase()];
				if(!aui_event) {
					aui_event = "click";
				}
			} else if(typeof aui_event != "string") {
				continue;
			}
			formElem.addAuiEventListener(aui_event, function() { // 放在事件里重新查询属性，标签可以被动态更改
				var aui_action = formElem.getAuiAttribute("aui-action");
				if(aui_action == null || aui_action.trim() == '') {
					console.debug(formElem);
					console.debug("aui-form is null, Unable to request.");
					return false;
				}
				var aui_method = findDefaultValue(formElem.getAuiAttribute("aui-method"),
						_this.config.get("form.method", "POST")),
					aui_async = findDefaultValue(formElem.getAuiAttribute("aui-async"),
						_this.config.get("form.async", true)),
					aui_result = findDefaultValue(formElem.getAttributeSP("aui-result", true), "none");
				var aui_resultMap = _this.config.get("from.resultMap", {});
				var resultCallFunction = aui_resultMap[aui_result];
				// create request data
				var requestData = {};
				var aui_checkError = false;
				var dataElems = _this.query(formElem);
				for(var y2 = 0; y2 < dataElems.length; y2++) {
					var dataElem = dataElems[y2];
					if(aui_checkError)
						continue;
					var aui_input = dataElem.getAuiAttribute("aui-input");
					if(!aui_input) {
						continue;
					}
					// 参数值寻找顺序(aui-value > aui-attrValue > value > text )
					var aui_value = dataElem.getAuiAttribute("aui-value");
					if(aui_value == null) {
						var aui_attrValue = dataElem.getAuiAttribute("aui-attrValue");
						if(aui_attrValue) {
							aui_value = dataElem[aui_attrValue];
							if(typeof aui_value == "undefined") {
								aui_value = dataElem.getAuiAttribute(aui_attrValue);
							} else {
								aui_value = String(aui_value);
							}
						}
					}
					if(aui_value == null) { // BUG:如果标签支持value属性，不管是否定义，都将返回""，不会触发innerText
						aui_value = dataElem.getAuiAttribute("value");
					}
					if(aui_value == null) {
						aui_value = dataElem.innerText;
					}
					if(aui_value != null) {
						// 数据校验 处理
						// aui-notnull="notnull"	数据校验不能为空
						if(aui_value.trim() == "") {
							var aui_notnull = dataElem.getAuiAttribute("aui-notnull");
							if(aui_notnull && (aui_notnull == "true" || aui_notnull == "notnull")) {
								if(!aui_checkErrorFunction(dataElem, "aui-notnull", aui_notnull, aui_input, aui_value)) {
									aui_checkError = true;
									break;
								}
							}
						}
						// aui-format="none|number|正则表达式"
						var aui_format = dataElem.getAuiAttribute("aui-format");
						if(aui_format && aui_format != "none") {
							if(aui_format == "number") {
								aui_format = "^[0-9]*$";
							}
							if(!new RegExp(aui_format).test(aui_value)) {
								if(!aui_checkErrorFunction(dataElem, "aui-format", aui_format, aui_input, aui_value)) {
									aui_checkError = true;
									break;
								}
							}
						}
						// aui-md5="md5"			数据处理方式，MD5数据摘要，[可选]
						var aui_md5 = dataElem.getAuiAttribute("aui-md5");
						if(aui_md5 && aui_md5.toLowerCase() == "md5") {
							aui_value = aui_hex_md5(aui_value);
						}
						requestData[aui_input] = aui_value;
					} else {
						// aui-must="true|false"		数据校验，数据参数必须存在	
						var aui_must = dataElem.getAuiAttribute("aui-must");
						if(aui_must && (aui_must == "true" || aui_must == "must")) {
							if(!aui_checkErrorFunction(dataElem, "aui-must", aui_must, aui_input, aui_value)) {
								aui_checkError = true;
								break;
							}
						}
					}
				}
				if(!aui_checkError) {
					// send request
					requestData = urlEncode(requestData);
					if(aui_method.toUpperCase() == 'POST') {
						_this.post(aui_action, requestData, resultCallFunction, formElem);
					} else {
						if(aui_action.indexOf('?') == -1) {
							aui_action += "?" + requestData;
						} else {
							aui_action += "&" + requestData;
						}
						_this.get(aui_action, resultCallFunction, formElem);
					}
				}
			});
		}
	});

	function ViewSyntax(aForm) {
		this.tempData = {};
		this.aForm = aForm;
		this.__switch__ = null;
		this.__switch__case_other_elem = null;
		this.__findCase = false;
	}
	// 语法方法名。根据顺序加载，当方法返回false时，后续方法将不会被加载
	ViewSyntax.syntax = ["_run", "_case", "_if", "_eachAttr", "_textAttr", "_htmlAttr", "_otherAttr"];
	ViewSyntax.syntaxAttrs = ["aui-run", "aui-switch", "aui-case", "aui-if", "aui-each", "aui-item", "aui-text", "aui-html"];
	ViewSyntax.displaySyntax = ["_textAttr", "_htmlAttr", "_otherAttr"];

	ViewSyntax.prototype.start = function(childrenElem) {
		this.childrenElem = childrenElem;
		childrenElem.style.visibility = "visible";
	}

	ViewSyntax.prototype.over = function() {
		var _this = this;
		if(_this.__switch__case_other_elem && _this.__findCase) {
			_this.__switch__case_other_elem.setDisplay(false);
		}
		var childrenElem = _this.childrenElem;
		// children
		_this.aForm.viewParsing(childrenElem);
	}

	ViewSyntax.prototype.destroy = function() {

	}

	ViewSyntax.prototype._run = function() {
		var _this = this;
		var childrenElem = _this.childrenElem;
		var aui_run = childrenElem.getAuiAttribute("aui-run");
		if(!aui_run)
			return true;
		var encode = _this.aForm.config.get("view.encode", "none");
		if (encode != 'none' && typeof encode == "function") {
			aui_run = encode.call(_this, aui_run, childrenElem);
		}
		// run js code
		try {
			eval(aui_run);
		} catch(e) {
			console.error(childrenElem);
			throw e;
		}
		return true;
	}

	ViewSyntax.prototype._case = function() {
		var _this = this;
		var childrenElem = _this.childrenElem;
		var aui_case = childrenElem.getAuiAttribute("aui-case");
		if(!aui_case)
			return true;
		if(_this.__switch__ == null) {
			try {
				_this.__switch__ = eval(childrenElem.findParentAttr("aui-switch"));
			} catch(e) {
				console.log(childrenElem);
				throw e;
			}
		}
		if(aui_case.trim() == '*') {
			_this.__switch__case_other_elem = childrenElem;
		} else {
			var caseValue;
			try {
				caseValue = eval(aui_case);
			} catch(e) {
				console.error(childrenElem);
				throw e;
			}
			var show = _this.__switch__ == caseValue;
			if(show) {
				_this.__findCase = true;
			}
			childrenElem.setDisplay(show);
			return show;
		}
		return true;
	}

	ViewSyntax.prototype._if = function() {
		var _this = this;
		var childrenElem = _this.childrenElem;
		var aui_if = childrenElem.getAuiAttribute("aui-if");
		if(!aui_if)
			return true;
		var show;
		try {
			show = eval(aui_if);
		} catch(e) {
			console.error(childrenElem);
			throw e;
		}
		if(typeof show != "boolean") {
			console.error(childrenElem);
			throw new TypeError("aui-if: 错误的类型，结果应为boolean。但是为" + show);
		}
		childrenElem.setDisplay(show);
		return show;
	}

	ViewSyntax.prototype._textAttr = function() {
		var _this = this;
		var childrenElem = _this.childrenElem;
		var aui_text = childrenElem.getAuiAttribute("aui-text");
		if(!aui_text)
			return true;
		try {
			aui_text = eval(aui_text);
			if(typeof aui_text == 'object') {
				try {
					aui_text = JSON.stringify(aui_text);
				} catch(e) {
					console.log(aui_text);
					throw e;
				}
			}
		} catch(e) {
			console.error(childrenElem);
			throw e;
		}
		childrenElem.innerText = aui_text;
		return true;
	}

	ViewSyntax.prototype._htmlAttr = function() {
		var _this = this;
		var childrenElem = _this.childrenElem;
		var aui_html = childrenElem.getAuiAttribute("aui-html");
		if(!aui_html)
			return true;
		try {
			aui_html = eval(aui_html);
		} catch(e) {
			console.error(childrenElem);
			throw e;
		}
		childrenElem.innerHTML = aui_html;
		return true;
	}

	ViewSyntax.prototype._otherAttr = function() {
		var _this = this;
		var childrenElem = _this.childrenElem;
		var attributes = childrenElem.attributes;
		if(!attributes)
			return true;
		for(var i = 0; i < attributes.length; i++) {
			var attributeName = attributes[i].name;
			/*if(ViewSyntax.syntaxAttrs.indexOf(attributeName) != -1) {
				continue;
			}*/
			if(attributeName.substring(0, 9) == "aui-data-") {
				var value;
				try {
					value = eval(attributes[i].value);
				} catch(e) {
					console.log(childrenElem);
					throw e;
				}
				childrenElem.setAttribute(attributeName.substring(9), value);
			}
		}
		return true;
	}

	ViewSyntax.prototype._eachAttr = function() {
		var _this = this;
		var childrenElem = _this.childrenElem;
		var aui_each = childrenElem.getAuiAttribute("aui-each"),
			aui_item = childrenElem.getAuiAttribute("aui-item");
		if(!aui_each) {
			return true;
		}
		if(!aui_item) {
			aui_item = "item";
		}
		// clear old
		var oldChildrenElems = childrenElem.parentNode.querySelectorAll("[temp-aui-each=" + aui_item + "]");
		for(var i = 0; i < oldChildrenElems.length; i++) {
			oldChildrenElems[i].parentNode.removeChild(oldChildrenElems[i]);
		}
		// get
		var eachArray;
		try {
			eachArray = eval(aui_each);
			if(!eachArray || !eachArray.forEach) {
				console.log(childrenElem);
				throw Error(aui_each + "无法进行each遍历!");
			}
		} catch(e) {
			console.log(childrenElem);
			throw e;
		}
		var tempCloneChildrenElem = null;
		eachArray.reverse();
		for(var y1 = 0; y1 < eachArray.length; y1++) {
			var eachItem = eachArray[y1];
			var cloneChildrenElem;
			if(tempCloneChildrenElem == null) {
				tempCloneChildrenElem = childrenElem.cloneNode(true);
				tempCloneChildrenElem.removeAttribute("aui-switch");
				tempCloneChildrenElem.removeAttribute("aui-case");
				tempCloneChildrenElem.removeAttribute("aui-if");
				tempCloneChildrenElem.removeAttribute("aui-each");
				tempCloneChildrenElem.removeAttribute("aui-item");
				tempCloneChildrenElem.setAttribute("temp-aui-each", aui_item);
				tempCloneChildrenElem.setDisplay(true);
				cloneChildrenElem = tempCloneChildrenElem;
			} else {
				cloneChildrenElem = tempCloneChildrenElem.cloneNode(true);
			}
			_this.start(cloneChildrenElem);
			var tempEval = "window." + aui_item + " = eachItem;";
			eval(tempEval);
			var displaySyntax = ViewSyntax.displaySyntax;
			for(var i = 0; i < displaySyntax.length; i++) {
				if(!_this[displaySyntax[i]].call(_this)) {
					break;
				}
			}
			_this.over();
			childrenElem.insertAfter(cloneChildrenElem);
		}
		childrenElem.setDisplay(false);
		return false; // 中断处理，each不能处理text、html以及其他标签属性
	}

	AForm.prototype.viewParsing = function(elem) {
		var _this = this;
		var childrenElems = elem.getChildren();
		if(childrenElems.length == 0)
			return;
		var viewSyntax = new ViewSyntax(_this);
		for(var y1 = 0; y1 < childrenElems.length; y1++) {
			var childrenElem = childrenElems[y1];
			viewSyntax.start(childrenElem);
			for(var i = 0; i < ViewSyntax.syntax.length; i++) {
				var result = viewSyntax[ViewSyntax.syntax[i]].call(viewSyntax);
				if(!result) {
					continue;
				}
			}
			viewSyntax.over();
		}
		viewSyntax.destroy();
	}

	AForm.register("view", function(scopeElem) {
		if(!scopeElem) {
			scopeElem = document;
		}
		var _this = this;
		if(!_this.view)
			_this.view = {};
		var aui_viewElems = scopeElem.querySelectorAll("[aui-view]");
		for(var i = 0; i < aui_viewElems.length; i++) {
			_this.viewParsing(aui_viewElems[i]);
		}
	}, true);
	

	/* Global */
	window.ACookie = ACookie;
	window.AForm = window.A$ = AForm;
});